home *** CD-ROM | disk | FTP | other *** search
- //=--------------------------------------------------------------------------=
- // FontColorCtl.Cpp
- //=--------------------------------------------------------------------------=
- // Copyright 1995 Microsoft Corporation. All Rights Reserved.
- //
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- // PARTICULAR PURPOSE.
- //=--------------------------------------------------------------------------=
- //
- #include "IPServer.H"
-
- #include "Guids.H"
- #include "FontColorCtl.H"
- #include "LocalObj.H"
- #include "Util.H"
- #include "Globals.H"
- #include "Resource.H"
-
- // for ASSERT and FAIL
- //
- SZTHISFILE
-
- //=--------------------------------------------------------------------------=
- // persistence helpers
- //
- #define STREAMHDR_MAGIC 0x12345678
-
- typedef struct {
-
- DWORD dwMagic;
- DWORD dwVersion;
- DWORD cbSize;
-
- } STREAMHDR;
-
- WCHAR wszForeColor [] = L"ForeColor";
- WCHAR wszFont [] = L"Font";
-
- static FONTDESC _fdDefault = {
- sizeof(FONTDESC),
- L"MS Sans Serif",
- FONTSIZE(12),
- FW_NORMAL,
- DEFAULT_CHARSET,
- FALSE,
- FALSE,
- FALSE
- };
-
-
-
- //=--------------------------------------------------------------------------=
- // array describing all of our property pages. these clsids are typically
- // in guids.h
- //
- // TODO: add any additional property page guids here ...
- //
- const GUID *rgFontColorPropPages [] = {
- &CLSID_FontColorGeneralPage
- };
-
- //=--------------------------------------------------------------------------=
- // Custum Verb information
- //
- // TODO: add any custom verbs here in an array, using the VERBINFO structure.
- // then mark the controld def'n in FontColorCtl.H with
- // this verb array
- //
-
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::Create
- //=--------------------------------------------------------------------------=
- // global static function that creates an instance of the control an returns
- // an IUnknown pointer for it.
- //
- // Parameters:
- // IUnknown * - [in] controlling unknown for aggregation
- //
- // Output:
- // IUnknown * - new object.
- //
- // Notes:
- //
- IUnknown *CFontColorControl::Create
- (
- IUnknown *pUnkOuter
- )
- {
- // make sure we return the private unknown so that we support aggegation
- // correctly!
- //
- CFontColorControl *pNew = new CFontColorControl(pUnkOuter);
- return pNew->PrivateUnknown();
- }
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::CFontColorControl
- //=--------------------------------------------------------------------------=
- // "Being born is like being kidnapped. And then sold into slavery."
- // - andy warhol (1928 - 87)
- //
- // Parameters:
- // IUnknown * - [in]
- //
- // Notes:
- //
- #pragma warning(disable:4355) // using 'this' in constructor
- CFontColorControl::CFontColorControl
- (
- IUnknown *pUnkOuter
- )
- : COleControl(pUnkOuter, OBJECT_TYPE_CTLFONTCOLOR, (IDispatch *)this)
- {
- m_state.ocForeColor = COLOR_WINDOWTEXT | 0x80000000;
- m_pFont = NULL;
-
- }
- #pragma warning(default:4355) // using 'this' in constructor
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::~CFontColorControl
- //=--------------------------------------------------------------------------=
- // "We all labour against our own cure, for death is the cure of all diseases"
- // - Sir Thomas Browne (1605 - 82)
- //
- // Notes:
- //
- CFontColorControl::~CFontColorControl ()
- {
- RELEASE_OBJECT(m_pFont);
- }
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl:RegisterClassData
- //=--------------------------------------------------------------------------=
- // register the window class information for your control here.
- // this information will automatically get cleaned up for you on DLL shutdown.
- //
- // Output:
- // BOOL - FALSE means fatal error.
- //
- // Notes:
- //
- BOOL CFontColorControl::RegisterClassData
- (
- void
- )
- {
- WNDCLASS wndclass;
-
- // TODO: register any additional information you find interesting here.
- // this method is only called once for each type of control
- //
- memset(&wndclass, 0, sizeof(WNDCLASS));
- wndclass.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
- wndclass.lpfnWndProc = COleControl::ControlWindowProc;
- wndclass.hInstance = g_hInstance;
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
- wndclass.lpszClassName = WNDCLASSNAMEOFCONTROL(OBJECT_TYPE_CTLFONTCOLOR);
-
- return RegisterClass(&wndclass);
- }
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::BeforeCreateWindow
- //=--------------------------------------------------------------------------=
- // called just before the window is created. Great place to set up the
- // window title, etc, so that they're passed in to the call to CreateWindowEx.
- // speeds things up slightly.
- //
- // Notes:
- //
- void CFontColorControl::BeforeCreateWindow
- (
- void
- )
- {
- // TODO: users should modify m_dwWindowStyle, m_dwWindowStyleEx, m_szWindowTitle
- // et al here so that the call to createwindow has as much information as
- // possible.
- // if you don't use this function, then you can probably just remove it.
- }
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::InternalQueryInterface
- //=--------------------------------------------------------------------------=
- // qi for things only we support.
- //
- // Parameters:
- // Parameters:
- // REFIID - [in] interface they want
- // void ** - [out] where they want to put the resulting object ptr.
- //
- // Output:
- // HRESULT - S_OK, E_NOINTERFACE
- //
- // Notes:
- //
- HRESULT CFontColorControl::InternalQueryInterface
- (
- REFIID riid,
- void **ppvObjOut
- )
- {
- IUnknown *pUnk;
-
- *ppvObjOut = NULL;
-
- // TODO: if you want to support any additional interrfaces, then you should
- // indicate that here. never forget to call COleControl's version in the
- // case where you don't support the given interface.
- //
- if (DO_GUIDS_MATCH(riid, IID_IFontColor)) {
- pUnk = (IUnknown *)(IFontColor *)this;
- } else{
- return COleControl::InternalQueryInterface(riid, ppvObjOut);
- }
-
- pUnk->AddRef();
- *ppvObjOut = (void *)pUnk;
- return S_OK;
- }
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::LoadTextState
- //=--------------------------------------------------------------------------=
- // load in our text state for this control.
- //
- // Parameters:
- // IPropertyBag * - [in] property bag to read from
- // IErrorLog * - [in] errorlog object to use with proeprty bag
- //
- // Output:
- // HRESULT
- //
- // Notes:
- // - NOTE: if you have a binary object, then you should pass an unknown
- // pointer to the property bag, and it will QI it for IPersistStream, and
- // get said object to do a Load()
- //
- STDMETHODIMP CFontColorControl::LoadTextState
- (
- IPropertyBag *pPropertyBag,
- IErrorLog *pErrorLog
- )
- {
- HRESULT hr;
- VARIANT v;
-
- v.vt = VT_I4;
- v.lVal = 0;
-
- // load in our forecolor and font properties.
- //
- hr = pPropertyBag->Read(wszForeColor, &v, pErrorLog);
- if (SUCCEEDED(hr)) m_state.ocForeColor = (OLE_COLOR)v.lVal;
-
- v.vt = VT_UNKNOWN;
- v.punkVal = NULL;
- hr = pPropertyBag->Read(wszFont, &v, pErrorLog);
- if (SUCCEEDED(hr)) {
- ASSERT(!m_pFont, "how come i already have a font??");
- hr = v.punkVal->QueryInterface(IID_IFont, (void **)&m_pFont);
- v.punkVal->Release();
- RETURN_ON_FAILURE(hr);
- }
-
- return S_OK;
- }
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::LoadBinaryState
- //=--------------------------------------------------------------------------=
- // loads in our binary state using streams.
- //
- // Parameters:
- // IStream * - [in] stream to write to.
- //
- // Output:
- // HRESULT
- //
- // Notes:
- //
- STDMETHODIMP CFontColorControl::LoadBinaryState
- (
- IStream *pStream
- )
- {
- IPersistStream *pps;
- STREAMHDR sh;
- HRESULT hr;
-
- // first read in the streamhdr, and make sure we like what we're getting
- //
- hr = pStream->Read(&sh, sizeof(sh), NULL);
- RETURN_ON_FAILURE(hr);
-
- // sanity check
- //
- if (sh.dwMagic != STREAMHDR_MAGIC || sh.cbSize != sizeof(m_state))
- return E_UNEXPECTED;
-
- // read in the control state information
- //
- hr = pStream->Read(&(m_state), sizeof(m_state), NULL);
- RETURN_ON_FAILURE(hr);
-
-
- // now read in the font!
- //
- OleCreateFontIndirect(&_fdDefault, IID_IFont, (void **)&m_pFont);
- RETURN_ON_NULLALLOC(m_pFont);
-
- // qi it for ipersiststream and load it in.
- //
- hr = m_pFont->QueryInterface(IID_IPersistStream, (void **)&pps);
- RETURN_ON_FAILURE(hr);
-
- hr = pps->Load(pStream);
- pps->Release();
-
- return hr;
- }
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::SaveTextState
- //=--------------------------------------------------------------------------=
- // saves out the text state for this control using a property bag.
- //
- // Parameters:
- // IPropertyBag * - [in] the property bag with which to work.
- // BOOL - [in] if TRUE, then write out ALL properties, even
- // if they're their the default value ...
- //
- // Output:
- // HRESULT
- //
- // Notes:
- //
- STDMETHODIMP CFontColorControl::SaveTextState
- (
- IPropertyBag *pPropertyBag,
- BOOL fWriteDefaults
- )
- {
- VARIANT v;
- HRESULT hr;
-
- // save out forecolor and font.
- //
- v.vt = VT_I4;
- v.lVal = (long) m_state.ocForeColor;
-
- if (m_state.ocForeColor != (COLOR_WINDOWTEXT | 0x80000000) || fWriteDefaults) {
- hr = pPropertyBag->Write(wszForeColor, &v);
- RETURN_ON_FAILURE(hr);
- }
-
- // CONSIDER: have some sort of way of knowning if we've got our own
- // font, or just the ambient font ...
- //
- if (m_pFont || fWriteDefaults) {
- if (!m_pFont) {
- IFontDisp *pfd;
- hr = get_Font(&pfd);
- RETURN_ON_FAILURE(hr);
- pfd->Release();
- }
- v.vt = VT_UNKNOWN;
- v.punkVal = m_pFont;
- hr = pPropertyBag->Write(wszFont, &v);
- RETURN_ON_FAILURE(hr);
- }
-
- return S_OK;
- }
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::SaveBinaryState
- //=--------------------------------------------------------------------------=
- // save out the binary state for this control, using the given IStream object.
- //
- // Parameters:
- // IStream * - [in] save to which you should save.
- //
- // Output:
- // HRESULT
- //
- // Notes:
- // - it is important that you seek to the end of where you saved your
- // properties when you're done with the IStream.
- //
- STDMETHODIMP CFontColorControl::SaveBinaryState
- (
- IStream *pStream
- )
- {
- IPersistStream *pps;
- IFontDisp *pfd;
- STREAMHDR sh = { STREAMHDR_MAGIC, MAKELONG(1, 0), sizeof(m_state) };
- HRESULT hr;
-
- // write out the stream hdr.
- //
- hr = pStream->Write(&sh, sizeof(sh), NULL);
- RETURN_ON_FAILURE(hr);
-
- // write out he control state information
- //
- hr = pStream->Write(&m_state, sizeof(m_state), NULL);
- RETURN_ON_FAILURE(hr);
-
- // now just save out the font.
- //
- hr = get_Font(&pfd);
- RETURN_ON_FAILURE(hr);
- hr = pfd->QueryInterface(IID_IPersistStream, (void **)&pps);
- pfd->Release();
- RETURN_ON_FAILURE(hr);
-
- hr = pps->Save(pStream, TRUE);
- pps->Release();
-
- return hr;
- }
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::OnDraw
- //=--------------------------------------------------------------------------=
- // "I don't very much enjoy looking at paintings in general. i know too
- // much about them. i take them apart."
- // - georgia o'keeffe (1887-1986)
- //
- // Parameters:
- // HDC - [in] HDC to draw to
- // LPCRECTL - [in] rect we're drawing to
- // LPCRECTL - [in] window extent and origin for meta-files
- // HDC - [in] HIC for target device
- //
- // Output:
- // HRESULT
- //
- // Notes:
- //
- HRESULT CFontColorControl::OnDraw
- (
- HDC hdcDraw,
- LPCRECTL prcBounds,
- LPCRECTL prcWBounds,
- HDC hicTargetDevice
- )
- {
- COLORREF rgb, rgbOld;
- HRESULT hr;
- IFontDisp *pFontDisp;
- IFont *pFont;
- HFONT hfont, hfontOld;
-
- // get our current font so we can get the HFONT for it!
- //
- hr = get_Font(&pFontDisp);
- RETURN_ON_FAILURE(hr);
-
- hr = pFontDisp->QueryInterface(IID_IFont, (void **)&pFont);
- pFontDisp->Release();
- RETURN_ON_FAILURE(hr);
-
- hr = pFont->get_hFont(&hfont);
- CLEANUP_ON_FAILURE(hr);
-
- // select the new font into the DC
- //
- hfontOld = SelectObject(hdcDraw, hfont);
-
- // get the color.
- //
- OleTranslateColor(m_state.ocForeColor, NULL, &rgb);
- rgbOld = SetTextColor(hdcDraw, rgb);
-
- DrawText(hdcDraw, "Happy Happy Joy Joy", -1, (LPRECT)prcBounds, DT_CENTER|DT_VCENTER);
-
- SelectObject(hdcDraw, hfontOld);
- SetTextColor(hdcDraw, rgbOld);
- hr = S_OK;
-
- CleanUp:
- pFont->Release();
-
- return hr;
- }
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::WindowProc
- //=--------------------------------------------------------------------------=
- // window procedure for this control. nothing terribly exciting.
- //
- // Parameters:
- // see win32sdk on window procs.
- //
- // Notes:
- //
- LRESULT CFontColorControl::WindowProc
- (
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam
- )
- {
- // TODO: handle any messages here, like in a normal window
- // proc. note that for special keys, you'll want to override and
- // implement OnSpecialKey.
- //
- return DefWindowProc(hwnd, msg, wParam, lParam);
- }
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::Invoke [IDispatch]
- //=--------------------------------------------------------------------------=
- // we have to override this method to look for properties of type Font,
- // Picture, or OLE_COLOR. turns out there is a bug in Ole Automation which
- // will cause TypeInfo::Invoke to blow up/fail when working with these types
- // since htey are from a nested type library. no es bueno.
- //
- // Parameters:
- // DISPID - [in] identifies the member we're working with.
- // REFIID - [in] must be IID_NULL.
- // LCID - [in] language we're working under
- // USHORT - [in] flags, propput, get, method, etc ...
- // DISPPARAMS * - [in] array of arguments.
- // VARIANT * - [out] where to put result, or NULL if they don't care.
- // EXCEPINFO * - [out] filled in in case of exception
- // UINT * - [out] where the first argument with an error is.
- //
- // Output:
- // HRESULT - tonnes of them.
- //
- // Notes:
- //
- STDMETHODIMP CFontColorControl::Invoke
- (
- DISPID dispid,
- REFIID riid,
- LCID lcid,
- WORD wFlags,
- DISPPARAMS *pdispparams,
- VARIANT *pvarResult,
- EXCEPINFO *pexcepinfo,
- UINT *puArgErr
- )
- {
- HRESULT hr;
-
- // only have to handle it for these properties, since they're the only
- // ones with STDOLE32 types ...
- //
- switch (dispid) {
- case DISPID_FONT:
- case DISPID_FORECOLOR:
- break;
-
- // just use the regular invoke we've got ...
- //
- default:
- return CAutomationObject::Invoke(dispid, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
- }
-
- // mask out methods, since we only are having problems with propgets and
- // propputs
- //
- wFlags &= (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF);
-
- // now, depending on what they're asking for, do something different.
- //
- switch (wFlags) {
- case DISPATCH_PROPERTYGET:
- ASSERT(pvarResult, "Duh! can't give a result back if i don't have a place to put it!");
- VariantClear(pvarResult);
- // make sure they didn't send us any arguments.
- //
- if (pdispparams && pdispparams->cArgs != 0) {
- FAIL("Gaaak! somebody sent some arguments!!!");
- return DISP_E_BADPARAMCOUNT;
- }
-
- // now just call the user routine
- //
- switch (dispid) {
- case DISPID_FONT:
- {
- IFontDisp *pFontDisp;
- pvarResult->vt = VT_DISPATCH;
- pvarResult->vt = NULL;
- hr = get_Font(&pFontDisp);
- RETURN_ON_FAILURE(hr);
- hr = pFontDisp->QueryInterface(IID_IDispatch, (void **)&(pvarResult->pdispVal));
- pFontDisp->Release();
- return hr;
- }
- break;
-
- case DISPID_FORECOLOR:
- pvarResult->vt = VT_I4;
- return get_ForeColor((OLE_COLOR *)&(pvarResult->lVal));
- }
- break;
-
- case DISPATCH_PROPERTYPUT:
- ASSERT(pdispparams && pdispparams->cArgs == 1, "D'oh! can't set a property without a value!");
-
- switch (dispid) {
- case DISPID_FORECOLOR:
- return put_ForeColor((OLE_COLOR)pdispparams->rgvarg[0].lVal);
- case DISPID_FONT:
- {
- IFontDisp *pfd;
- hr = get_Font(&pfd);
- RETURN_ON_FAILURE(hr);
- hr = pfd->Invoke(DISPID_VALUE, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
- pfd->Release();
- return hr;
- }
- break;
- default:
- FAIL("Nobody should ever trip this!!!");
- }
-
- case DISPATCH_PROPERTYPUTREF:
- ASSERT(pdispparams && pdispparams->cArgs == 1, "Can't set a property without a value! Maggots!");
- switch (dispid) {
- case DISPID_FONT:
- {
- IFontDisp *pFontDisp;
- hr = pdispparams->rgvarg[0].punkVal->QueryInterface(IID_IFontDisp, (void **)&pFontDisp);
- RETURN_ON_FAILURE(hr);
- hr = put_Font(pFontDisp);
- pFontDisp->Release();
- return hr;
- }
- break;
- default:
- FAIL("This should never be called!");
- }
-
- }
-
- FAIL("D'oh! i shouldn't see DISPATCH_METHOD when i'm only working with properites!");
- return DISP_E_MEMBERNOTFOUND;
- }
-
-
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::AboutBox [IFontColor]
- //=--------------------------------------------------------------------------=
- // prints up an about box. fweeeee.
- //
- // Notes:
- //
- void CFontColorControl::AboutBox
- (
- void
- )
- {
- // TODO: Ideally, one would use DialogBox, and some sort of Dialog Box here if
- // they wanted a slightly more interesting About Box ... you should
- // still call ModalDialog first, however.
- //
- ModalDialog(TRUE);
- MessageBox(NULL, "This is My Control", "About FontColor", MB_OK | MB_TASKMODAL);
- ModalDialog(FALSE);
- }
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::get_Font [IFontColor]
- //=--------------------------------------------------------------------------=
- // returns the current font.
- //
- // Parameters:
- // IFontDisp ** -[out] figure it out.
- //
- // Output:
- // HRESULT
- //
- // Notes:
- //
- STDMETHODIMP CFontColorControl::get_Font
- (
- IFontDisp **ppFont
- )
- {
- CHECK_POINTER(ppFont);
-
- if (!m_pFont)
- GetAmbientFont(&m_pFont);
-
- if (m_pFont)
- return m_pFont->QueryInterface(IID_IFontDisp, (void **)ppFont);
-
- *ppFont = NULL;
- return E_UNEXPECTED;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::put_Font [IFontColor]
- //=--------------------------------------------------------------------------=
- // sets the current font.
- //
- // Parameters:
- // IFontDisp *pFont - [in] duh.
- //
- // Output:
- // HRESULT
- //
- // Notes:
- //
- STDMETHODIMP CFontColorControl::put_Font
- (
- IFontDisp *pFont
- )
- {
- HRESULT hr;
-
- RELEASE_OBJECT(m_pFont);
-
- // if we have a new font, get it, and do some cleaning up!
- //
- if (pFont) {
- hr = pFont->QueryInterface(IID_IFont, (void **)&m_pFont);
- RETURN_ON_FAILURE(hr);
- }
-
- InvalidateControl(NULL);
- PropertyChanged(DISPID_FONT);
- m_fDirty = TRUE;
- return S_OK;
- }
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::get_ForeColor [IFontColor]
- //=--------------------------------------------------------------------------=
- // returns current forecolor.
- //
- // Parameters:
- // OLE_COLOR * - [out]. duh.
- //
- // Output:
- // HRESULT
- //
- // Notes:
- //
- STDMETHODIMP CFontColorControl::get_ForeColor
- (
- OLE_COLOR *pocForeColor
- )
- {
- CHECK_POINTER(pocForeColor);
-
- *pocForeColor = m_state.ocForeColor;
- return S_OK;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CFontColorControl::put_ForeColor [IFontColor]
- //=--------------------------------------------------------------------------=
- // sets current foreground color.
- //
- // Parameters:
- // OLE_COLOR - [in]
- //
- // Output:
- // HRESULT
- //
- // Notes:
- //
- STDMETHODIMP CFontColorControl::put_ForeColor
- (
- OLE_COLOR ocForeColor
- )
- {
- m_state.ocForeColor = ocForeColor;
- InvalidateControl(NULL);
- m_fDirty = TRUE;
- return S_OK;
- }
-
-
-